package hanxx.security.controller;

import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONObject;
import hanxx.common.config.PlatformConfig;
import hanxx.common.fileUtils.ExcelUtil;
import hanxx.common.fileUtils.FileUploadUtils;
import hanxx.common.fileUtils.MimeTypeUtils;
import hanxx.common.utils.*;
import hanxx.common.utils.coding.Constants;
import hanxx.common.utils.http.HttpUtils;
import hanxx.common.utils.ip.AddressUtils;
import hanxx.common.utils.ip.IpUtils;
import hanxx.kafka.produce.KafkaConsumerConfig;
import hanxx.kafka.produce.KafkaProducerConfig;
import hanxx.menu.domain.SysMenu;
import hanxx.security.domain.SysUser;
import hanxx.security.domain.SysUserLogin;
import hanxx.security.service.SysRoleService;
import hanxx.security.service.SysUserService;
import hanxx.system.controller.BaseController;
import hanxx.system.page.PageDomain;
import hanxx.system.page.TableDataInfo;
import org.redisson.Redisson;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.kafka.annotation.KafkaListener;
import org.springframework.kafka.config.ConcurrentKafkaListenerContainerFactory;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.List;

/**
 * edit:韩鑫鑫
 * 部门:产品研发三部
 **/
@RestController
public class SysUserController extends BaseController {
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private PasswordEncoder passwordEncoder;
    @Autowired
    private SysRoleService roleService;

    @PostMapping(value = "login")
    public AjaxResult login(@RequestBody SysUser sysUser){
        String encode = passwordEncoder.encode("666666");
        /*SysUser sysUser1 = new SysUser();
        sysUser1.setId(SnowflakeIdWorker.idWorker.nextId());
        sysUser1.setUserName("哈哈哈哈");
        sysUser1.setPassword(passwordEncoder.encode("33333"));
        sysUser1.setRemark("1");
        sysUserService.save(sysUser1);*/
        AjaxResult ajaxResult = sysUserService.login(sysUser);
        return ajaxResult;
    }

    /**
     * 获得当前登录用户信息1
     * @return
     */
    @PostMapping(value = "getInfo")
    public AjaxResult getInfo(){
        AjaxResult ajaxResult = new AjaxResult();
        SysUserLogin userLogin = getUserLogin();
//        userLogin.setSysUser(sysUserService.get(userLogin.getSysUser().getUserId()));

        if (StringUtils.isEmpty(userLogin.getSysUser().getLoginPosition())&&StringUtils.isNotEmpty(userLogin.getSysUser().getLoginIp())){
            String realAddressByIP = AddressUtils.getRealAddressByIP(userLogin.getSysUser().getLoginIp());
            userLogin.getSysUser().setLoginPosition(realAddressByIP);
            sysUserService.flashLastLoginTimeAndIp(userLogin.getSysUser());
        } else if (StringUtils.isEmpty(userLogin.getSysUser().getLoginIp())){
            sysUserService.flashLastLoginTimeAndIp(userLogin.getSysUser());
        }

        ajaxResult.put("user",userLogin.getSysUser());
        ajaxResult.put("permissions",userLogin.getPermissions());
        ajaxResult.put("roles",userLogin.getRoles());



        return ajaxResult;
    }

    /**
     * 退出处理，由于security封装的有退出接口，比较方便，所以这里没有用到此接口
     * 前端退出连接为url:"/logout"
     * @return
     */
    @PostMapping(value = "loginout")
    public AjaxResult loginout(){
        AjaxResult ajaxResult = sysUserService.loginout();
        return ajaxResult;
    }

    @PostMapping("/user/export")
    public void export(HttpServletResponse response) throws IOException {
        List<SysUser> all = sysUserService.findAll();
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        util.exportExcel(response,all,"用户信息");
//        util.importTemplateExcel(response,"4444");
    }

    @PostMapping("/user/exportModel")
    public void exportModel(HttpServletResponse response) throws IOException {
        List<SysUser> all = sysUserService.findAll();
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
//        util.exportExcel(response,all,"用户信息");
        util.importTemplateExcel(response,"用户信息模板");
    }

    @PostMapping("/user/importData")
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        List<SysUser> sysUsers = util.importExcel(file.getInputStream());
        String message = sysUserService.importData(sysUsers,updateSupport);
        return AjaxResult.success("请求成功了");
    }

    @PostMapping("/user/avatar")
    public AjaxResult avatar(@RequestParam("avatarfile") MultipartFile file) throws Exception{
        if (!file.isEmpty()){
            String avatar = FileUploadUtils.upload(PlatformConfig.getAvatarPath(), file, MimeTypeUtils.IMAGE_EXTENSION,true);
            AjaxResult ajax = AjaxResult.success();
            ajax.put("imgUrl", avatar);
            SysUser sysUser = getSysUser();
            sysUser.setAvatar(avatar);
            sysUserService.update(sysUser);
            sysUserService.flushUserLogin(getUserLogin());
            return ajax;
        } else{
            return AjaxResult.error("图片上传失败");
        }
    }

    @GetMapping(value = "/user/getUsers")
    public TableDataInfo getUsers(SysUser sysUser, PageDomain pageDomain){
        TableDataInfo tableDataInfo = sysUserService.getUsers(sysUser,pageDomain);
        return tableDataInfo;
    }

    @PostMapping(value = "/user/save")
    public AjaxResult save(@RequestBody SysUser sysUser){
        try {
            sysUser.setUserId(SnowflakeIdWorker.idWorker.nextId());
            sysUser.setCreateTime(DateUtils.getNowDate());
            sysUser.setPassword(passwordEncoder.encode(sysUser.getPassword()));
            sysUser.setRemark("1");
            sysUserService.save(sysUser);
            return AjaxResult.success("添加用户成功！");
        } catch (Exception e){
            return AjaxResult.error("添加用户失败"+e);
        }
    }

    /*private static ThreadLocal<SysMenu> threadLocal;
    static {
        threadLocal = new ThreadLocal<>();
    }*/

    @PostMapping(value = "/user/test1")
//    @PreAuthorize("hasAuthority('test')")
    @PreAuthorize("@ss.hasPermi('test1')")
    public AjaxResult test1(SysUser sysUser) throws InterruptedException {
//        final SecurityContext context = SecurityContextHolder.getContext();   //获取当前登录用户的Security信息
//        sysUserService.threadLocal();                                         //通过ThreadLocal存储对象信息，信息存入到了线程里面
//        System.out.println(Thread.currentThread().getName());                 //获取当前线程
//        sysUserService.kafkaMqProduct();                                      //kafka测试
        /*String pay = sysUserService.pay(333l);                                //redis分布式锁测试--没有使用redisson依赖
        return AjaxResult.success("支付信息："+pay);*/
//        sysUserService.hashedWheelTimer();                                    //时间轮，定时
        /*String s = sysUserService.payRedisson(44444l);                        //redis分布式锁测试--使用了redisson依赖
        return AjaxResult.success(s);*/
        sysUserService.testOtherPleace();                                       //测试专用通道
        return AjaxResult.success("登录成功后的操作完成！");
    }


    @PostMapping(value = "/user/update")
    public AjaxResult update(@RequestBody SysUser sysUser){
        try {
//            获取登录者的ip地址
            /*final RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();
            final ServletRequestAttributes requestAttributes1 = (ServletRequestAttributes) requestAttributes;
            final HttpServletRequest request = requestAttributes1.getRequest();
            final String ip = IpUtils.getIpAddr(ServletUtils.getRequest());*/

            /*final String ipAddr = IpUtils.getIpAddr(ServletUtils.getRequest());
            String ip = "ip=123.162.56.215&json=true";
            final String realAddressByIP = AddressUtils.getRealAddressByIP(ip);

            String rspStr = HttpUtils.sendGet(AddressUtils.IP_URL, ip, Constants.GBK);
            JSONObject obj = JSON.parseObject(rspStr);*/

//            Menu menu = threadLocal.get();
//            Menu menu = BaseEntityCache.get();
            /*SysUser sysUser11 = BaseEntityCache.get("SysUser");
            Menu menu = BaseEntityCache.get("Menu");
            System.out.println(Thread.currentThread().getName());*/

            SysUser sysUser1 = sysUserService.get(sysUser.getUserId());
            BeanUtils.copyBeanProp(sysUser1,sysUser,BeanUtils.getNullField(sysUser));
//            sysUser1.setUserName(sysUser.getUserName());
            sysUser1.setUpdateTime(sysUser.getUpdateTime());
            /*if (!sysUser.getPassword().equals(sysUser1.getPassword())){
                sysUser1.setPassword(passwordEncoder.encode(sysUser.getPassword()));
            }*/
            sysUserService.update(sysUser1);
            getUserLogin().setSysUser(sysUser1);
            sysUserService.flushUserLogin(getUserLogin());
            return AjaxResult.success("用户信息更新成功");
        } catch (Exception e){
            return AjaxResult.error("用户信息更新失败");
        }
    }

    @GetMapping(value = "/user/updateUserPwd/{oldPassword}/{newPassword}")
    public AjaxResult update(@PathVariable String oldPassword,@PathVariable String newPassword){
        SysUser sysUser = getSysUser();
        if (passwordEncoder.matches(oldPassword,sysUser.getPassword())){
            sysUser.setPassword(passwordEncoder.encode(newPassword));
            sysUserService.update(sysUser);
            sysUserService.flushUserLogin(getUserLogin());
            return AjaxResult.success("密码修改成功");
        }
        return AjaxResult.success("密码修改失败");
    }

    @DeleteMapping("user/{id}")
    public AjaxResult delete(@PathVariable Long id){
        try {
            sysUserService.delete(id);
            return AjaxResult.success("删除成功");
        } catch (Exception e){
            return AjaxResult.error("删除失败");
        }
    }
}
